﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using DAL;
using Utils.Exceptions;
using Utils.Web;
using Utils.ControlToLoad;
using System.Collections.Generic;

namespace Prototype1
{
    //tem que receber o expenseReport de algum lado
    public partial class FormExpenseLine : PageWithDDlAndId
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                this.DataBind();
                this.ControlId = Guid.NewGuid();
            }
            else
            {
                // if (!string.IsNullOrEmpty(this.SelectedControlName))
                // {
                //     Control c = Page.LoadControl(this.SelectedControlName);
                //     this.ph_ControlHolder.Controls.Clear();
                //     this.ph_ControlHolder.Controls.Add(c);
                //     ((IControlToLoadRW)c).Bind(this.ControlId, this.IdR);
                //}

                using (DataAccessDataContext dc = new DataAccessDataContext())
                {
                    var result = from t in dc.Templates
                                 select t;
                    IEnumerator templates = result.GetEnumerator();
                    while (templates.MoveNext())
                    {
                        String controlName = ((Template)(templates.Current)).EditControl;
                        Control c = Page.LoadControl("EditControls\\" + controlName);
                        //try { ((IControlToLoadRW)c).Bind(this.ControlId, this.IdR); }
                        //catch { }
                        this.ph_ControlHolder.Controls.Add(c);
                    }
                }
            }
        }

        //id do expenseType seleccionado
        public Guid IdR
        {
            get
            {
                if (ViewState["IdR"] != null)
                    return (Guid)ViewState["IdR"];
                else
                    throw new ValueNotAvailableException();
            }
            set { ViewState["IdR"] = value; }
        }

        public override void DataBind()
        {
            using (DataAccessDataContext dc = new DataAccessDataContext())
            {
                this.ddl_ExpenseTypes.DataSource = from t in dc.ExpenseTypes
                                                   select t;
                base.DataBind();
            }
        }

        protected void ddl_ExpenseTypes_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.IdR = new Guid(this.ddl_ExpenseTypes.SelectedValue);
            using (DataAccessDataContext dc = new DataAccessDataContext())
            {
                var query = from t in dc.ExpenseTypes
                            where t.Id.Equals(this.IdR)
                            select t.Template;
                Template temp = query.Single<Template>();

                this.SelectedControlName = "EditControls\\" + temp.EditControl;
                //Control c = Page.LoadControl(this.SelectedControlName);
                //((IControlToLoadRW)c).Bind(this.ControlId, this.IdR);
                //this.ph_ControlHolder.Controls.Clear();
                //this.ph_ControlHolder.Controls.Add(c);

            }
        }

        protected void bt_submit_Click(object sender, EventArgs ea)
        {
            ExpenseLine expl = new ExpenseLine();
            String description = this.tb_description.Text;
            String justification = this.tb_Justification.Text;
            DateTime date = this.Calendar.SelectedDate;
            String expReportId = this.tb_expReportId.Text;
            //verificar se existe um report com este ID..
            expl.ExpenseReportId = new Guid(expReportId);
            expl.Date = date;
            if (this.tb_Justification.Visible)
                expl.Justification = justification;
            expl.Id = this.ControlId;
            //o this.IdR pode ainda não estar bem se for clickado no botão de submit sem ter nenhum seleccionado
            expl.ExpenseTypeId = this.IdR;
            expl.Description = description;
            using (DataAccessDataContext da = new DataAccessDataContext())
            {
                da.ExpenseLines.InsertOnSubmit(expl);
                da.SubmitChanges();
            }
            if (string.IsNullOrEmpty(this.SelectedControlName))
            {
                return;
            }
            Type t = Page.LoadControl(this.SelectedControlName).GetType();
            IEnumerator phControls = this.ph_ControlHolder.Controls.GetEnumerator();
            while (phControls.MoveNext())
            {
                if (t == phControls.Current.GetType())
                {
                    //Prototype1.EditControls.ControlTemplateSimple c =
                    //    (Prototype1.EditControls.ControlTemplateSimple)phControls.Current;
                    //Prototype1.EditControls.ControlTemplateDislocations c = 
                    //    (Prototype1.EditControls.ControlTemplateDislocations)phControls.Current;
                    IControlToLoadRW ictrw = (IControlToLoadRW)phControls.Current;
                    ictrw.Bind(this.ControlId, this.IdR);
                    ictrw.Save(); 
                }
            }
        }

        //aqui só deixo ficar aquele que está selecionado. Se não estiver nenhum selecionado n fica nenhum.
        protected override void OnLoadComplete(EventArgs ea)
        {
            base.OnLoadComplete(ea);
            if (string.IsNullOrEmpty(this.SelectedControlName))
            {
                this.ph_ControlHolder.Controls.Clear();
                return;
            }
            //mal feito, devia ser carregado o tipo a partir da string para evitar este LoadControl
            Type t = Page.LoadControl(this.SelectedControlName).GetType();

            //se o controlo não for o selecionado é removido
            IEnumerator phControls = this.ph_ControlHolder.Controls.GetEnumerator();
            List<object> toRemove = new List<object>();
            while (phControls.MoveNext())
            {
                if (t != phControls.Current.GetType())
                    toRemove.Add(phControls.Current);
                else
                    ((IControlToLoadRW)(phControls.Current)).Bind(this.ControlId, this.IdR);
            }
            foreach(object o in toRemove)
            {
                this.ph_ControlHolder.Controls.Remove((Control)o);
            }
            //Ver nas configurações da parte comum o que tem que estar visível ou não
            using (DataAccessDataContext da = new DataAccessDataContext())
            {
                var query = from e in da.ExpenseTypes
                            where e.Id.Equals(this.IdR)
                            select e;
                ExpenseType expType = query.Single<ExpenseType>();
                if (expType.RequiresJust.Value)
                {
                    this.lb_Justification.Visible = true;
                    this.tb_Justification.Visible = true;
                }
                else
                {
                    this.lb_Justification.Visible = false;
                    this.tb_Justification.Visible = false;
                }
            }
        }
    }
}
